package com.log.search.util;

import cn.hutool.core.util.StrUtil;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.log.search.entity.Shell;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ShellUtils {

  public static Session getSession(Shell shell) {
    JSch jsch = new JSch();
    try {
      //创建session并且打开连接，因为创建session之后要主动打开连接
      Session session = jsch.getSession(shell.getUsername(), shell.getIp(), shell.getPort());
      session.setConfig("StrictHostKeyChecking", "no");
      if (StrUtil.isBlank(shell.getPassword())) {
        jsch.setKnownHosts("~/.ssh/known_hosts");
        jsch.addIdentity("~/.ssh/id_rsa");
      } else {
        session.setPassword(shell.getPassword());
      }
      session.connect();
      return session;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  public static List<String> exec(Shell shell, String command) {
    Session session = null;
    ChannelExec channelExec = null;
    BufferedReader input = null;
    InputStreamReader inputStreamReader = null;
    List<String> outList = new ArrayList<>();
    try {
      //打开通道，设置通道类型，和执行的命令
      session = getSession(shell);
      if (null == session) {
        return outList;
      }
      channelExec = (ChannelExec) session.openChannel("exec");
      channelExec.setCommand(command);
      channelExec.setInputStream(null);
      inputStreamReader = new InputStreamReader(channelExec.getInputStream(), StandardCharsets.UTF_8);
      input = new BufferedReader(inputStreamReader);

      channelExec.connect();
      //接收远程服务器执行命令的结果
      String line;
      while ((line = input.readLine()) != null) {
        outList.add(line);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (null != input) {
        try {
          input.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != channelExec) {
        channelExec.disconnect();
        if (channelExec.isClosed()) {
          return outList;
        }
      }
      if (null != inputStreamReader) {
        try {
          inputStreamReader.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (null != session) {
        session.disconnect();
      }
    }
    return outList;
  }

  /**
   * 执行本地命令
   *
   * @param cmd 命令
   * @return 日志list
   */
  public static List<String> getLocalList(String cmd) {
    List<String> outList = new ArrayList<>();
    Process process = null;
    try {
      process = Runtime.getRuntime().exec(new String[]{"sh","-c",cmd});
      try (
          InputStreamReader ips = new InputStreamReader(process.getInputStream());
          BufferedReader input = new BufferedReader(ips);
      ) {
        String line;
        while ((line = input.readLine()) != null) {
          outList.add(line);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }

    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      if (process != null) {
        process.destroy();
      }

    }

    return outList;
  }

}
